package com.example.nio.one;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;

/**
 * @Description
 * @Author 26233
 * @Create 2021-10-27 21:19:03
 */

/**
 * 一个accept Selector
 * 多个线程，每个线程一个read Selector 处理读写
 */
public class MultiSelectorServer {
    int size = 4;
    Selector[] selectors = new Selector[size];
    ReadSelectorThread[] readSelectorThreads = new ReadSelectorThread[size];

    public void init(){
        for (int i = 0; i < readSelectorThreads.length; i++) {
            try {
                selectors[i] = SelectorProvider.provider().openSelector();
            } catch (IOException e) {
                e.printStackTrace();
            }
            readSelectorThreads[i] = new ReadSelectorThread(selectors[i]);
            new Thread(readSelectorThreads[i]).start();
//            System.out.println("thread " + i + " start...");
        }
    }

    public void start() throws IOException {
        String hostName = "192.168.101.8";
        int port = 8888;

        Selector acceptSelector = Selector.open();
        ServerSocketChannel acceptSocketChannel = ServerSocketChannel.open();
        acceptSocketChannel.bind(new InetSocketAddress(hostName, port));
        acceptSocketChannel.configureBlocking(false);
        acceptSocketChannel.register(acceptSelector, SelectionKey.OP_ACCEPT);

        System.out.println("echo start");

        init();

        int selectorIndex = 0;
        while (true){
            acceptSelector.select();
            Set<SelectionKey> selectionKeys = acceptSelector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                iterator.remove();
                try{
                    if (selectionKey.isValid()){
                        if (selectionKey.isAcceptable()){
                            System.out.println("accept");
                            ServerSocketChannel acceptChannel = (ServerSocketChannel) selectionKey.channel();
                            SocketChannel client = acceptChannel.accept();
                            client.configureBlocking(false);

                            if (selectorIndex > 3){
                                selectorIndex = 0;
                            }
                            selectors[selectorIndex].wakeup();
                            client.register(selectors[selectorIndex++], SelectionKey.OP_READ);
                        }else if (selectionKey.isReadable()){
                            System.out.println("key is readable");
                            SocketChannel channel = (SocketChannel) selectionKey.channel();
                            ByteBuffer recv = ByteBuffer.allocate(1024);
                            int read = channel.read(recv);
                        }else{
                            System.out.println("key is not accept");
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    selectionKey.channel().close();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new MultiSelectorServer().start();
    }
}